package demo.xml.jaxen.custom;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.jaxen.BaseXPath;
import org.jaxen.Context;
import org.jaxen.JaxenException;
import org.jaxen.javabean.DocumentNavigator;
import org.jaxen.javabean.Element;

import com.titan.core.utils.data.JaxenUtils;

public class CustomXPath extends BaseXPath {
    private static final long serialVersionUID = -1567521943360266313L;

    /** Construct given an XPath expression string.
     *
     *  @param xpathExpr The XPath expression.
     *
     *  @throws JaxenException if there is a syntax error while
     *          parsing the expression
     */
    public CustomXPath(String xpathExpr) throws JaxenException
    {
        super( xpathExpr, CustomNavigator.getInstance() );
    }

    protected Context getContext(Object node) {
        if (node instanceof Context) {
            return (Context) node;
        }

        if (node instanceof Element) {
            return super.getContext(node);
        }

        if (node instanceof List) {
            List newList = new ArrayList();

            for (Iterator listIter = ((List) node).iterator(); listIter.hasNext();) {
                newList.add(new Element(null, "root", listIter.next()));
            }

            return super.getContext(newList);
        }

        return super.getContext(new Element(null, "root", node));
    }

    public Object evaluate(Object node) throws JaxenException {
        Object result = super.evaluate(node);
        JaxenUtils.print("evaluate", result);

        if (result instanceof Element) {
            return ((Element) result).getObject();
        } else if (result instanceof Collection) {
            List newList = new ArrayList();

            for (Iterator listIter = ((Collection) result).iterator(); listIter.hasNext();) {
                Object member = listIter.next();

                if (member instanceof Element) {
                    newList.add(((Element) member).getObject());
                } else {
                    newList.add(member);
                }
            }
            return newList;
        }

        return result;
    }
}
